package za.org.jcicada.genss.alarm.katcp;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import za.org.jcicada.comms.impl.KatcpSerializerStrategy;
import za.org.jcicada.comms.messages.CommsMessage;
import za.org.jcicada.genss.alarm.AlarmStatus;
import za.org.jcicada.genss.alarm.AlarmURN;
import za.org.jcicada.genss.alarm.IAlarm;
import za.org.jcicada.genss.alarm.impl.Alarm;
import za.org.jcicada.genss.alarm.messages.AcknowledgeAlarmReply;
import za.org.jcicada.genss.alarm.messages.AcknowledgeAlarmRequest;
import za.org.jcicada.genss.alarm.messages.AlarmInform;
import za.org.jcicada.genss.alarm.messages.AlarmSetReply;
import za.org.jcicada.genss.alarm.messages.AlarmSetRequest;
import za.org.jcicada.genss.alarm.messages.AttachReply;
import za.org.jcicada.genss.alarm.messages.AttachRequest;
import za.org.jcicada.genss.alarm.messages.DetachReply;
import za.org.jcicada.genss.alarm.messages.DetachRequest;
import za.org.jcicada.genss.messages.TerminateServiceInform;

public class AlarmKatcpSerializer extends KatcpSerializerStrategy {
    
    public AlarmKatcpSerializer() {
        super(new Marshal(), new Unmarshal());
    }

    public static class Marshal {
        public String[] getSetURN(Set<AlarmURN> uris) {
            List<String> uriList = new ArrayList<String>();
            for (AlarmURN uri: uris) {
                uriList.add(uri.toString());
            }
            return uriList.toArray(new String[0]);
        }
        
        public Object[] AcknowledgeAlarmReply(AcknowledgeAlarmReply msg) {
            return new Object[] { msg.getCode(), msg.getMessage(), msg.getAlarmURN() };
        }
        
        public Object[] AcknowledgeAlarmRequest(AcknowledgeAlarmRequest msg) {
            return new Object[] { msg.getAlarmURN() };
        }
        
        public Object[] AlarmInform(AlarmInform msg) {
            return new Object[] { msg.getAlarmURN(), msg.getAlarm().getStatus(), msg.getAlarm().getMessage() };
        }
        
        public Object[] AlarmSetReply(AlarmSetReply msg) {
        	Object[] args = new Object[] { msg.getCode(), msg.getMessage() };
            return concatenate(args, getSetURN(msg.getAlarmURNs()));
        }
    
        public Object[] AlarmSetRequest(AlarmSetRequest msg) {
            return new Object[] { };
        }
            
        public Object[] AttachReply(AttachReply msg) {
            return new Object[] { msg.getCode(), msg.getMessage()};
        }
    
        public Object[] AttachRequest(AttachRequest msg) {
            return new Object[] { };
        }
        
        public Object[] DetachReply(DetachReply msg) {
            return new Object[] { msg.getCode(), msg.getMessage() };
        }
    
        public Object[] DetachRequest(DetachRequest msg) {
            return new Object[] { };
        }
        
        public Object[] TerminateServiceInform(TerminateServiceInform msg) {
            return new Object[] { msg.getServiceURN() };
        }
    }
    
    public static class Unmarshal {
        
        public Set<AlarmURN> getSetURN(String[] arg, int from) {
            Set<AlarmURN> urns = new HashSet<AlarmURN>();
            for (int i = from; i < arg.length; i++) {
                urns.add(parseAlarmURN(arg, i));
            }
            return urns;
        }
        
        public CommsMessage AcknowledgeAlarmReply(String[] args) {
            return new AcknowledgeAlarmReply(parseResult(args), parseAlarmURN(args, 2));
        }
    
        public CommsMessage AcknowledgeAlarmRequest(String[] args) {
            return new AcknowledgeAlarmRequest(parseAlarmURN(args, 0));
        }
        
        public CommsMessage AlarmInform(String[] args) {
            AlarmURN alarmURN = parseAlarmURN(args, 0);
            IAlarm alarm = new Alarm(AlarmStatus.valueOf(args[1]), alarmURN, args[2]);
            return new AlarmInform(alarmURN, alarm);
        }
        
        public CommsMessage AlarmSetReply(String[] args) {
            return new AlarmSetReply(parseResult(args), getSetURN(args, 2));
        }
    
        public CommsMessage AlarmSetRequest(String[] args) {
            return new AlarmSetRequest();
        }
        
        public CommsMessage AttachReply(String[] args) {
            return new AttachReply(parseResult(args));
        }
        
        public CommsMessage AttachRequest(String[] args) {
            return new AttachRequest();
        }
        
        public CommsMessage DetachReply(String[] args) {
            return new DetachReply(parseResult(args));
        }
    
        public CommsMessage DetachRequest(String[] args) {
            return new DetachRequest();
        }
            
        public CommsMessage TerminateServiceInform(String[] args) {
            return new TerminateServiceInform(parseAlarmURN(args, 0));
        }
            
    }
}
